﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using XingLucifer.Devices.Protocols;
using XingLucifer.IBase;

namespace XingLucifer.Devices
{
    public class KVPLC废弃 : IDevices
    {
        private CancellationTokenSource _tokenSource;

        private ICommunication _com;
        public KVPLC废弃(ICommunication com, CancellationTokenSource tokenSource)
        {
            _com = com;
            _tokenSource = tokenSource;
        }

        public bool Open() => _com.Open();

        public void Close() => _com.Close();

        public Task Read()
        {
            throw new NotImplementedException("未实现");
        }

        public TClass ReadClass<TClass>(int address, TClass obj = null, int count = 3) where TClass : class
        {
            throw new NotImplementedException("未实现");
        }

        public TValue? ReadSingle<TValue>(int address, int length, int count = 3)
        {
            throw new NotImplementedException("未实现");
        }

        public bool WriteClass<TClass>(TClass value, int address, int count = 3) where TClass : class
        {
            throw new NotImplementedException("未实现");
        }

        public bool WriteSingle(object value, int address, int offset, int length, int count = 3)
        {
            throw new NotImplementedException("未实现");
        }

        /// <summary>
        ///   方法来将字符串转换为一个 List<UInt16>，其中每两个字节被组合成一个 UInt16 字，每两个字节存储在一个字内，一个字字节存储在低八位，另一个字节存储在高八位
        /// </summary>
        /// <param name="addr"></param>
        /// <param name="values"></param>
        /// <returns></returns>
        public bool WriteStringAsUInt16(string addr, string values)
        {
            var vals = new List<UInt16>();

            for (int i = 0; i < values.Length; i += 2)
            {
                char lowChar = values[i];
                char highChar = (i + 1 < values.Length) ? values[i + 1] : '\0';  // '\0' 表示空字符

                byte lowByte = (byte)(lowChar & 0xFF);      // 取低八位
                byte highByte = (byte)(highChar & 0xFF);    // 取高八位

                UInt16 combinedValue = (UInt16)((lowByte << 8) | highByte);  // 组合成一个 UInt16 值，互换高低字节
                vals.Add(combinedValue);
            }

            return Write<UInt16>(addr, vals.ToArray());
        }


        public bool WriteString(string addr, string values)
        {
            var z1 = Encoding.Default.GetBytes(values);
            var vals = new List<UInt16>();
            for (var i = 0; i < z1.Length; i++)
            {
                var b = z1[i];
                var bytes = new List<byte>();
                if (b > 127)
                {
                    bytes.Add(z1[i]);
                    bytes.Add(z1[i + 1]);
                    i++;
                }
                else
                {
                    bytes.Add(z1[i]);
                    bytes.Add((byte)0);
                }
                var hex = "";
                foreach (var bb in bytes)
                {
                    hex += bb.ToString("X2");
                }
                var bbb = UInt16.Parse(hex, System.Globalization.NumberStyles.HexNumber);
                vals.Add(bbb);
            }
            return Write<UInt16>(addr, vals.ToArray());
        }


        /// <summary>
        /// 写入
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="addr"></param>
        /// <param name="values"></param>
        /// <returns></returns>
        public bool Write<T>(string addr, T[] values)
        {
            var wcmd = $"WRS {addr} {values.Length} {string.Join(" ", values)}\r\n";
            var bytes = new byte[4096];
            var readLen = 0;
            var result = _com.Write(Encoding.Default.GetBytes(wcmd));
            if(result)
            {
                var str = Encoding.Default.GetString(bytes.Take(readLen).ToArray());
                return str.Contains("OK") ? true : false;
            }
            return false;
        }

        public static string ConvertToBinaryString(ushort number)
        {
            string binaryString = "";
            for (int i = 15; i >= 0; i--)
            {
                char binaryDigit = (number & (1 << i)) == 0 ? '0' : '1';
                binaryString += binaryDigit;
            }
            return binaryString;
        }


        public bool ReadAndReturnBit(string addr)
        {
            try
            {
                // 构造读取指令，读取地址去掉后两位先保留
                string addrWithoutLastTwoDigits = addr.Substring(0, addr.Length - 2);
                var binaryResult = Read(addrWithoutLastTwoDigits, 1);
                if (binaryResult == null) return false;
                // 获取该数字的二进制表示
                string binaryString = ConvertToBinaryString(binaryResult[0]);

                // 从地址字符串中提取后两位数字
                string lastTwoDigits = addr.Substring(addr.Length - 2);

                // 将后两位数字转换为整数值
                int reservedValue = int.Parse(lastTwoDigits, NumberStyles.HexNumber);

                //倒数
                int index = binaryString.Length - reservedValue - 1;

                return binaryString[index].ToString() == "1" ? true : false;
            }
            catch (Exception ex)
            {
                // 出现异常时，关闭连接并设置连接状态为false
                return false;
            }
        }
        //private object readLocker=new object();
        //public List<UInt16> Read(string addr, int count)
        //{
        //    try
        //    {
        //        var bytes = new byte[1024];
        //        var cmd = $"RDS {addr} {count}\r\n";
        //        var str1 = "";
        //        var vals = new List<UInt16>();
        //        lock (readLocker)
        //        {
        //            var result = _com.Write(Encoding.Default.GetBytes(cmd));
        //            if (result)
        //            {
        //                var len = _com.Receive(bytes);
        //                bytes = bytes.Take(len).ToArray();
        //                str1 = Encoding.Default.GetString(bytes).Trim();
        //                // $"PLC:{string.Join(";",str1)}".Info();
        //                var str1s = str1.Split(' ');
        //                //try
        //                //{

        //                    for (var i = 0; i < str1s.Length; i++)
        //                    {
        //                        vals.Add(UInt16.Parse(str1s[i]));
        //                    }
        //                    return vals;
        //                //}
        //                //catch (Exception ex)
        //                //{
        //                //    Console.WriteLine(ex);
        //                //}

        //            }
        //        }

        //        return null;

        //    }
        //    catch (Exception ex)
        //    {
        //        return null;
        //    }
        //}
        public List<UInt16> Read(string addr, int count)
        {
            try
            {
                var bytes = new byte[1024];
                var cmd = $"RDS {addr} {count}\r\n";
                var str1 = "";
                var vals = new List<UInt16>();
             
                    var result = _com.SendToRead(Encoding.ASCII.GetBytes(cmd),2);

                str1 = Encoding.Default.GetString(result).Trim();
                // $"PLC:{string.Join(";",str1)}".Info();
                var str1s = str1.Split(' ');
                //try
                //{

                for (var i = 0; i < str1s.Length; i++)
                {
                    vals.Add(UInt16.Parse(str1s[i]));
                }
                return vals;

                //if (result)
                //{
                //    var len = _com.Receive(bytes);
                //    bytes = bytes.Take(len).ToArray();
                //    str1 = Encoding.Default.GetString(bytes).Trim();
                //    // $"PLC:{string.Join(";",str1)}".Info();
                //    var str1s = str1.Split(' ');
                //    //try
                //    //{

                //        for (var i = 0; i < str1s.Length; i++)
                //        {
                //            vals.Add(UInt16.Parse(str1s[i]));
                //        }
                //        return vals;
                //    //}
                //    //catch (Exception ex)
                //    //{
                //    //    Console.WriteLine(ex);
                //    //}

                return null;

            }
            catch (Exception ex)
            {
                return null;
            }
        }

        //public List<UInt16> Read(string addr, int count)
        //{
        //    try
        //    {
        //        var bytes = new byte[1024];
        //        var cmd = $"RDS {addr} {count}\r\n";
        //        var str1 = "";
        //        var vals = new List<UInt16>();
        //        lock (readLocker)
        //        {
        //            var result = _com.Write(Encoding.ASCII.GetBytes(cmd));
        //            var len = _com.Receive(bytes);
        //            while (len == 0)
        //            {
        //                len = _com.Receive(bytes);
        //                Thread.Sleep(50);
        //            }
        //            bytes = bytes.Take(len).ToArray();
        //        }

        //        str1 = Encoding.ASCII.GetString(bytes).Trim();
        //        // $"PLC:{string.Join(";",str1)}".Info();
        //        var str1s = str1.Split(' ');
        //        for (var i = 0; i < str1s.Length; i++)
        //        {
        //            vals.Add(UInt16.Parse(str1s[i]));
        //        }
        //        return vals;
        //    }
        //    catch (Exception ex)
        //    {
        //        return null;
        //    }
        //}

        public string ReadString(string addr, int count)
        {
            try
            {
                var values = Read(addr, count);
                var bytes = new List<byte>();
                if (values != null)
                    for (int i = 0; i < values.Count; i++)
                    {
                        var v = values[i];
                        var h = (byte)((v >> 8) & 0x00ff);
                        var l = (byte)(v & 0x00ff);
                        if (h > 0)
                            bytes.Add(h);
                        if (l > 0)
                            bytes.Add(l);
                    }
                var s = Encoding.Default.GetString(bytes.ToArray());
                return Encoding.Default.GetString(bytes.ToArray());
            }

            catch (Exception ex)
            {
                return "";
            }
        }

        string IDevices.Read()
        {
            throw new NotImplementedException();
        }

        public Dictionary<string, string> CircuitTesterReceive()
        {
            throw new NotImplementedException();
        }
    }
}
